"""
通用工具函数
"""
import hashlib
import json
import time
import random
import string
from datetime import datetime, timedelta
from typing import Any, Dict, List, Optional, Union
import re
from pathlib import Path


def generate_random_string(length: int = 8) -> str:
    """生成随机字符串"""
    chars = string.ascii_letters + string.digits
    return ''.join(random.choice(chars) for _ in range(length))


def generate_timestamp() -> int:
    """生成时间戳"""
    return int(time.time())


def format_timestamp(timestamp: int, fmt: str = "%Y-%m-%d %H:%M:%S") -> str:
    """格式化时间戳"""
    return datetime.fromtimestamp(timestamp).strftime(fmt)


def md5_hash(data: str) -> str:
    """计算MD5哈希值"""
    return hashlib.md5(data.encode('utf-8')).hexdigest()


def sha256_hash(data: str) -> str:
    """计算SHA256哈希值"""
    return hashlib.sha256(data.encode('utf-8')).hexdigest()


def validate_email(email: str) -> bool:
    """验证邮箱格式"""
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return bool(re.match(pattern, email))


def validate_phone(phone: str) -> bool:
    """验证手机号格式"""
    pattern = r'^1[3-9]\d{9}$'
    return bool(re.match(pattern, phone))


def safe_json_loads(data: str) -> Optional[Dict[str, Any]]:
    """安全地解析JSON字符串"""
    try:
        return json.loads(data)
    except (json.JSONDecodeError, TypeError):
        return None


def safe_json_dumps(data: Any, ensure_ascii: bool = False) -> str:
    """安全地序列化为JSON字符串"""
    try:
        return json.dumps(data, ensure_ascii=ensure_ascii, separators=(',', ':'))
    except (TypeError, ValueError):
        return ""


def chunk_list(lst: List[Any], chunk_size: int) -> List[List[Any]]:
    """将列表分割成指定大小的块"""
    return [lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size)]


def flatten_list(nested_list: List[List[Any]]) -> List[Any]:
    """展平嵌套列表"""
    return [item for sublist in nested_list for item in sublist]


def get_file_size(file_path: Union[str, Path]) -> int:
    """获取文件大小（字节）"""
    path = Path(file_path)
    if path.exists() and path.is_file():
        return path.stat().st_size
    return 0


def human_readable_size(size_bytes: int) -> str:
    """将字节大小转换为人类可读格式"""
    if size_bytes == 0:
        return "0B"
    
    units = ['B', 'KB', 'MB', 'GB', 'TB']
    unit_index = 0
    size = float(size_bytes)
    
    while size >= 1024 and unit_index < len(units) - 1:
        size /= 1024
        unit_index += 1
    
    return f"{size:.2f}{units[unit_index]}"


def retry_on_exception(max_retries: int = 3, delay: float = 1.0):
    """异常重试装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            for attempt in range(max_retries):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_retries - 1:
                        raise e
                    time.sleep(delay * (2 ** attempt))  # 指数退避
            return None
        return wrapper
    return decorator


def timer(func):
    """计时装饰器"""
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"函数 {func.__name__} 执行时间: {end_time - start_time:.4f}秒")
        return result
    return wrapper


def singleton(cls):
    """单例装饰器"""
    instances = {}
    
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper


class Stopwatch:
    """计时器类"""
    
    def __init__(self):
        self.start_time = None
        self.end_time = None
    
    def start(self):
        """开始计时"""
        self.start_time = time.time()
        self.end_time = None
    
    def stop(self) -> float:
        """停止计时并返回耗时"""
        self.end_time = time.time()
        return self.elapsed_time
    
    @property
    def elapsed_time(self) -> float:
        """获取已用时间"""
        if self.start_time is None:
            return 0.0
        end_time = self.end_time or time.time()
        return end_time - self.start_time


def mask_sensitive_data(data: str, visible_chars: int = 4) -> str:
    """脱敏敏感数据"""
    if len(data) <= visible_chars * 2:
        return "*" * len(data)
    
    visible_start = data[:visible_chars]
    visible_end = data[-visible_chars:]
    return f"{visible_start}****{visible_end}"


def deep_merge_dicts(dict1: Dict, dict2: Dict) -> Dict:
    """深度合并两个字典"""
    result = dict1.copy()

    for key, value in dict2.items():
        if (key in result and isinstance(result[key], dict)
            and isinstance(value, dict)):
            result[key] = deep_merge_dicts(result[key], value)
        else:
            result[key] = value

    return result


def validate_password(password: str) -> bool:
    """验证密码格式（至少8位，包含字母和数字）"""
    if len(password) < 8:
        return False
    has_letter = bool(re.search(r'[a-zA-Z]', password))
    has_digit = bool(re.search(r'\d', password))
    return has_letter and has_digit


def create_response(data: Any = None, message: str = "success", status_code: int = 200) -> Dict[str, Any]:
    """创建标准响应格式"""
    return {
        "status_code": status_code,
        "message": message,
        "data": data,
        "timestamp": int(time.time())
    }


def create_error_response(message: str, status_code: int = 400, error_code: str = "UNKNOWN_ERROR") -> Dict[str, Any]:
    """创建错误响应格式"""
    return {
        "status_code": status_code,
        "error_code": error_code,
        "message": message,
        "data": None,
        "timestamp": int(time.time())
    }